from collections import Counter
import os

ENCODING = 'utf8'

resultPath = "temp_result.txt"
srcDir = "../../blkparse/"
FPSZ = 256 # blkparse文件中, 一个hash的长度(目前只解析为字符串)

def analyzeBlkparse1(path: str):
    shitCnt = 0
    rwCounter = Counter()
    blkCounter = Counter()
    hashCounter = Counter()
    with open(path, 'r', encoding=ENCODING) as f:
        for line in f:
            elems = line.strip().split(' ')
            blk, rw, hash_line = int(elems[4]), elems[5], elems[8]

            # 检查hash长度是否正确, 防止文件错误
            # if len(hash_line) != blk * FPSZ // 8:
            #     print(f"Error: {path}")
            #     print(f"blk: {blk}, hash_len: {len(hash_line)}")
            #     return
            
            # 读写块数不为8的倍数
            # if blk % 8 != 0:
            #     shitCnt += 1
            #     continue

            if rw == 'W':
                for j in range(0, len(hash_line), FPSZ):
                    hashCounter[hash_line[j:j+FPSZ]] += 1
            blkCounter[blk] += 1
            rwCounter[rw] += 1

    print(path)
    print(f"shitCnt: {shitCnt}")
    
    # 空文件
    rwSum = sum(rwCounter.values())
    if rwSum == 0:
        return ""
    
    # 输出结果
    return f"{os.path.basename(path)}\n" + \
        str(blkCounter) + '\n' + \
        str(rwCounter) + '\n' + \
        f"rwRate: R:{rwCounter['R'] / rwSum:.4f} W:{rwCounter['W'] / rwSum:.4f}\n" + \
        f"shitCnt: {shitCnt}\n" + \
        "maxBlkCnt: " + str(max(blkCounter.keys())) + '\n' + \
        f"duplication: {1 - len(hashCounter) / rwCounter['W']:.4f}\n" + \
        '\n'


def analyzeHitsztrace(path: str):
    hashCounter = Counter()
    print(path)
    with open(path, 'r', encoding=ENCODING) as f:
        for line in f:
            elems = line.strip().split(' ')
            lbn, dataHash = int(elems[2]), elems[3]
            assert len(dataHash) in [32, 40]
            hashCounter[dataHash] += 1
    
    # 输出结果
    return f"{os.path.basename(path)}\n" + \
        f"duplication: {1 - len(hashCounter) / sum(hashCounter.values()):.4f}\n" + \
        f"dataSize: {sum(hashCounter.values()) * 4 / 1024 / 1024:.4f} GB\n" + \
        f"uniqueSize: {len(hashCounter) * 4 / 1024 / 1024:.4f} GB"


def analyzeBlkparse(path: str):
    cnt = 0
    shitCnt = 0
    hashCounter = Counter()
    with open(path, 'r', encoding=ENCODING) as f:
        for line in f:
            elems = line.strip().split(' ')
            blk, rw, hash_line = int(elems[4]), elems[5], elems[8]

            if blk % 8 != 0:
                shitCnt += 1
                continue

            blkCnt = blk // 8
            cnt += blkCnt
            if rw == 'W':
                for j in range(0, len(hash_line), len(hash_line) // blkCnt):
                    hashCounter[hash_line[j:j+len(hash_line) // blkCnt]] += 1

    # print(path)
    # assert cnt == sum(hashCounter.values())
    print(cnt, sum(hashCounter.values()))
    print(path)
    # 输出结果
    return f"dataSize: {cnt * 4 / 1024 / 1024:.4f} GB\n" + \
        f"duplication: {1 - len(hashCounter.keys()) / cnt:.4f}\n" + \
        f"shitCnt: {shitCnt}\n"
        # f"dataSize: {cnt * 4 / 1024 / 1024:.4f} GB"
        # "wPageCnt: " + str(cnt) + '\n'


def main():
    import sys
    if len(sys.argv) < 2:
        print("Usage: python count_blkparse.py <blkparseDir>")
        return
    path = sys.argv[1]
    if path.endswith(".blkparse"):
        print(analyzeBlkparse(path))
    elif path.endswith('.hitsztrace'):
        print(analyzeHitsztrace(path))
    else:
        print("file should be .blkparse or .hitsztrace")

if __name__ == '__main__':
    main()
